package com.teaching.teachingsupport.service.impl.teacherserviceimpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.teaching.teachingsupport.common.enums.NotificationScopeTypeEnum;
import com.teaching.teachingsupport.common.pojo.dataobject.NotificationScope;
import com.teaching.teachingsupport.common.pojo.dataobject.Student;
import com.teaching.teachingsupport.common.pojo.dataobject.Notification;
import com.teaching.teachingsupport.common.pojo.dto.request.NotificationPublishRequest;
import com.teaching.teachingsupport.mapper.*;
import com.teaching.teachingsupport.mapper.studentviewmapper.NotificationMapper;
import com.teaching.teachingsupport.mapper.studentviewmapper.StudentMapper;
import com.teaching.teachingsupport.service.service2.teacherservice.NotificationScopeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class NotificationScopeServiceImpl implements NotificationScopeService {

    private final NotificationScopeMapper notificationScopeMapper;
    private final StudentMapper studentMapper;
    private final CollegeInfoMapper collegeInfoMapper;
    private final MajorDirectionMapper majorDirectionMapper;
    private final NotificationMapper notificationMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Notification publishNotification(NotificationPublishRequest request) {
        // 1. 基础参数验证
        if (request == null) {
            throw new IllegalArgumentException("通知请求不能为空");
        }
        if (StringUtils.isEmpty(request.getTitle())) {
            throw new IllegalArgumentException("通知标题不能为空");
        }
        if (StringUtils.isEmpty(request.getContent())) {
            throw new IllegalArgumentException("通知内容不能为空");
        }

        // 2. 获取目标用户群
        Set<Long> targetUserIds = new HashSet<>();
        
        // 处理全校可见
        if (Boolean.TRUE.equals(request.getIsSchoolWide())) {
            // 获取所有学生ID
            List<Student> allStudents = studentMapper.selectList(null);
            if (allStudents.isEmpty()) {
                throw new IllegalArgumentException("系统中没有任何学生信息");
            }
            targetUserIds.addAll(allStudents.stream()
                    .map(Student::getUserId)
                    .collect(Collectors.toSet()));
        } else {
            // 检查是否至少指定了一个筛选条件
            boolean hasAnyFilter = !CollectionUtils.isEmpty(request.getColleges()) ||
                                !CollectionUtils.isEmpty(request.getDepartments()) ||
                                !CollectionUtils.isEmpty(request.getMajors()) ||
                                !CollectionUtils.isEmpty(request.getGrades()) ||
                                !CollectionUtils.isEmpty(request.getClassIds());
            
            if (!hasAnyFilter) {
                throw new IllegalArgumentException("请至少指定一个筛选条件（学院、系别、专业、年级或班级），或选择全校可见");
            }

            // 构建查询条件
            LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
            
            // 添加学院条件（精确匹配）
            if (!CollectionUtils.isEmpty(request.getColleges())) {
                wrapper.in(Student::getCollege, request.getColleges());
            }
            
            // 添加系别条件（精确匹配）
            if (!CollectionUtils.isEmpty(request.getDepartments())) {
                wrapper.in(Student::getDepartment, request.getDepartments());
            }
            
            // 添加专业条件（精确匹配）
            if (!CollectionUtils.isEmpty(request.getMajors())) {
                wrapper.in(Student::getMajor, request.getMajors());
            }
            
            // 添加年级条件（确保格式为"YYYY级"）
            if (!CollectionUtils.isEmpty(request.getGrades())) {
                List<String> formattedGrades = request.getGrades().stream()
                    .map(grade -> grade.endsWith("级") ? grade : grade + "级")
                    .collect(Collectors.toList());
                wrapper.in(Student::getGrade, formattedGrades);
            }
            
            // 添加班级条件
            if (!CollectionUtils.isEmpty(request.getClassIds())) {
                wrapper.in(Student::getClassId, request.getClassIds());
            }
            
            // 执行查询
            List<Student> students = studentMapper.selectList(wrapper);
            
            // 如果没有找到学生，给出更详细的错误信息
            if (students.isEmpty()) {
                StringBuilder errorMsg = new StringBuilder("未找到符合以下条件的学生：");
                if (!CollectionUtils.isEmpty(request.getColleges())) {
                    errorMsg.append("\n学院: ").append(String.join(", ", request.getColleges()));
                }
                if (!CollectionUtils.isEmpty(request.getDepartments())) {
                    errorMsg.append("\n系别: ").append(String.join(", ", request.getDepartments()));
                }
                if (!CollectionUtils.isEmpty(request.getMajors())) {
                    errorMsg.append("\n专业: ").append(String.join(", ", request.getMajors()));
                }
                if (!CollectionUtils.isEmpty(request.getGrades())) {
                    errorMsg.append("\n年级: ").append(String.join(", ", request.getGrades()));
                }
                if (!CollectionUtils.isEmpty(request.getClassIds())) {
                    errorMsg.append("\n班级ID: ").append(request.getClassIds());
                }
                throw new IllegalArgumentException(errorMsg.toString());
            }

            targetUserIds.addAll(students.stream()
                    .map(Student::getUserId)
                    .collect(Collectors.toSet()));
        }

        // 3. 创建通知记录
        // 首先创建一条主通知记录
        Notification mainNotification = new Notification();
        mainNotification.setUserId(targetUserIds.iterator().next()); // 使用第一个用户ID
        mainNotification.setTitle(request.getTitle());
        mainNotification.setContent(request.getContent());
        mainNotification.setType(request.getType());
        mainNotification.setRelatedLink(request.getRelatedLink());
        mainNotification.setCreatedTime(LocalDateTime.now());
        mainNotification.setIsRead(0);  // 默认未读
        notificationMapper.insert(mainNotification);

        // 为其他用户创建通知记录，复用主通知的ID
        for (Long userId : targetUserIds) {
            if (!userId.equals(mainNotification.getUserId())) { // 跳过主通知的用户
                Notification notification = new Notification();
                notification.setUserId(userId);
                notification.setTitle(request.getTitle());
                notification.setContent(request.getContent());
                notification.setType(request.getType());
                notification.setRelatedLink(request.getRelatedLink());
                notification.setCreatedTime(mainNotification.getCreatedTime());
                notification.setIsRead(0);
                notificationMapper.insert(notification);
            }
        }

        // 4. 记录通知范围 - 只记录一次
        if (Boolean.TRUE.equals(request.getIsSchoolWide())) {
            // 全校通知
            NotificationScope scope = createScope(mainNotification.getNotificationId(), 
                    NotificationScopeTypeEnum.SCHOOL.getCode(), null);
            notificationScopeMapper.insert(scope);
        } else {
            // 记录学院范围
            if (!CollectionUtils.isEmpty(request.getColleges())) {
                for (String college : request.getColleges()) {
                    // 这里需要通过collegeInfoMapper获取college_id
                    Long collegeId = collegeInfoMapper.getCollegeIdByName(college);
                    if (collegeId != null) {
                        NotificationScope scope = createScope(mainNotification.getNotificationId(),
                                NotificationScopeTypeEnum.COLLEGE.getCode(), collegeId);
                        notificationScopeMapper.insert(scope);
                    }
                }
            }

            // 记录专业范围
            if (!CollectionUtils.isEmpty(request.getMajors())) {
                for (String major : request.getMajors()) {
                    // 这里需要通过majorDirectionMapper获取major_id
                    Long majorId = majorDirectionMapper.getMajorIdByName(major);
                    if (majorId != null) {
                        NotificationScope scope = createScope(mainNotification.getNotificationId(),
                                NotificationScopeTypeEnum.MAJOR.getCode(), majorId);
                        notificationScopeMapper.insert(scope);
                    }
                }
            }

            // 记录班级范围
            if (!CollectionUtils.isEmpty(request.getClassIds())) {
                for (Long classId : request.getClassIds()) {
                    NotificationScope scope = createScope(mainNotification.getNotificationId(),
                            NotificationScopeTypeEnum.CLASS.getCode(), classId);
                    notificationScopeMapper.insert(scope);
                }
            }
        }

        return mainNotification;
    }

    @Override
    public List<Notification> getVisibleNotifications(Long userId) {
        // 直接从notification表查询该用户的通知
        return notificationMapper.selectList(
            new LambdaQueryWrapper<Notification>()
                .eq(Notification::getUserId, userId)
                .orderByDesc(Notification::getCreatedTime)
        );
    }

    @Override
    public void deleteByNotificationId(Long notificationId) {
        LambdaQueryWrapper<NotificationScope> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NotificationScope::getNotificationId, notificationId);
        notificationScopeMapper.delete(wrapper);
    }

    private NotificationScope createScope(Long notificationId, Integer scopeType, Long targetId) {
        NotificationScope scope = new NotificationScope();
        scope.setNotificationId(notificationId);
        scope.setScopeType(scopeType);
        scope.setTargetId(targetId);
        return scope;
    }
} 